package com.sqlcheck.entity;

import com.baomidou.mybatisplus.annotation.*;
import com.sqlcheck.util.JsonUtils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("sql_statements")
public class SqlStatement {
    
    @TableId(type = IdType.AUTO)
    private Long id;
    
    // 核心标识
    @TableField("task_id")
    private Long taskId;
    
    @TableField("statement_number")
    private Integer statementNumber;  // 任务内序号
    
    @TableField("sql_content_hash")
    private String contentHash;
    
    // SQL信息
    @TableField("sql_content")
    private String content;
    
    @TableField("sql_type")
    private SqlType sqlType;
    
    @TableField("ddl_type")
    private DdlType ddlType;  // 仅DDL扫描使用
    
    @TableField("source_type")
    private SourceType sourceType;
    
    // 文件位置信息（相对路径）
    @TableField("source_file")
    private String sourceFile;  // 相对于项目根目录的路径
    
    @TableField("line_number")
    private Integer lineNumber;
    
    @TableField("column_number")
    private Integer columnNumber;
    
    @TableField("class_name")
    private String className;
    
    @TableField("method_name")
    private String methodName;
    
    // Java注解详细信息
    @TableField("java_annotation_type")
    private JavaAnnotationType javaAnnotationType;
    
    @TableField("mybatis_xml_element")
    private MybatisXmlElement mybatisXmlElement;
    
    // 数据库对象信息
    @TableField("primary_table")
    private String primaryTable;
    
    @TableField("affected_tables")
    private String affectedTablesText;  // 存储为逗号分隔的字符串
    
    @TableField("database_objects")
    private String databaseObjectsJson;  // JSON字符串
    
    @TableField("extraction_metadata")
    private String extractionMetadataJson; // JSON字符串
    
    @TableField("is_native_query")
    private Boolean isNativeQuery;
    
    @TableField("is_derived_query")
    private Boolean isDerivedQuery;
    
    // 时间字段
    @TableField(value = "created_at", fill = FieldFill.INSERT)
    private LocalDateTime createdAt;
    
    @TableField(value = "updated_at", fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updatedAt;
    
    @TableLogic
    @TableField("deleted")
    private Boolean deleted;
    
    // 枚举定义
    public enum SqlType {
        QUERY, DML, DDL, PROCEDURE, FUNCTION, TRIGGER
    }
    
    public enum DdlType {
        CREATE_TABLE, CREATE_INDEX, CREATE_VIEW, 
        CREATE_PROCEDURE, CREATE_FUNCTION, CREATE_TRIGGER,
        ALTER_TABLE, DROP_TABLE, DROP_INDEX, OTHER
    }
    
    public enum SourceType {
        MYBATIS_XML, MYBATIS_ANNOTATION, JPA_ANNOTATION, 
        NATIVE_QUERY, MANUAL_INPUT, DDL_SCRIPT
    }
    
    public enum JavaAnnotationType {
        QUERY, MODIFYING, NATIVE_QUERY, JPQL, CRITERIA
    }
    
    public enum MybatisXmlElement {
        SELECT, INSERT, UPDATE, DELETE, SQL
    }
    
    // 辅助方法
    public List<String> getAffectedTables() {
        if (affectedTablesText == null || affectedTablesText.trim().isEmpty()) {
            return new ArrayList<>();
        }
        return Arrays.asList(affectedTablesText.split(","))
                .stream()
                .map(String::trim)
                .filter(s -> !s.isEmpty())
                .collect(Collectors.toList());
    }
    
    public void setAffectedTables(List<String> tables) {
        if (tables == null || tables.isEmpty()) {
            this.affectedTablesText = null;
        } else {
            this.affectedTablesText = String.join(",", tables);
        }
    }
    
    public Map<String, Object> getDatabaseObjects() {
        return JsonUtils.safeParseMap(databaseObjectsJson);
    }
    
    public void setDatabaseObjects(Map<String, Object> objects) {
        this.databaseObjectsJson = JsonUtils.safeToJsonString(objects);
    }
    
    public Map<String, Object> getExtractionMetadata() {
        return JsonUtils.safeParseMap(extractionMetadataJson);
    }
    
    public void setExtractionMetadata(Map<String, Object> metadata) {
        this.extractionMetadataJson = JsonUtils.safeToJsonString(metadata);
    }
}